// -------------------------------------------------------------------------------------
// PPPMonitor.m
// (Indent:4, Tabs:4)
// -------------------------------------------------------------------------------------
// Copyright 1996 Persistent Technologies, Inc. - all rights reserved
// -------------------------------------------------------------------------------------
// This source code comes with no warranty of any kind, and the user assumes all 
// responsibility for its use.
// -------------------------------------------------------------------------------------
#import <libc.h>
#import <stdlib.h>
#import <string.h>
#import <ctype.h>
#import <appkit/appkit.h>
#import "PPPMonitor.h"
#import "ExecMonitor.h"

// -------------------------------------------------------------------------------------
// user default vector

static NXDefaultsVector _userDefaults = {
	{"CmdConnect"     , 0 },	// 0
	{"SndConnect"     , 0 },	// 1
	{"AppIconTimer"   , 0 },	// 2
	{"CmdDisconnect"  , 0 },	// 3
	{"SndDisconnect"  , 0 },	// 4
	{"CmdTailLog"     , 0 },	// 5
	{"CmdPing"        , 0 },	// 6
	{"CmdPingInterval", 0 },	// 7
	{"MiniShelf"      , 0 },	// 8
	{"CmdLoadPPPLKS"  , 0 },	// 9
	{"MiniShelfTile"  , 0 },	// 10
	{"MiniShelfDots"  , 0 },	// 11
	{NULL,0}
};

// -------------------------------------------------------------------------------------
@implementation PPPMonitor

// -------------------------------------------------------------------------------------
// misc
// -------------------------------------------------------------------------------------

/* return app (owner) name */
- (const char*)appName
{
	return "PPPMonitor";
}

/* run alert panel */
- (int)errorPanel:(const char*)msg
{
    return NXRunAlertPanel("Error", msg, "OK", (char*)nil, (char*)nil);
}

// -------------------------------------------------------------------------------------
// menu actions
// -------------------------------------------------------------------------------------

/* clear monitor text window */
- (void)clearLog:(id)sender
{
	[[ExecMonitor sharedPPPMonitor] clearLog:sender];
}

/* application termination */
- terminate:sender
{
	if ([ExecMonitor canShutDown]) {
		if (![ExecMonitor shutDown]) {
			[self perform:_cmd with:sender afterDelay:500 cancelPrevious:YES];
			return (id)nil;
		}
		return [super terminate:sender];
	}
	NXBeep();
	[NSApp errorPanel:"Cannot quit while connection is still active"];
	return (id)nil;
}

// -------------------------------------------------------------------------------------
// user defaults
// -------------------------------------------------------------------------------------

/* read user default */
- (const char*)readDefault:(const char*)name
{
	return NXReadDefault([self appName],name);
}

/* return user default for specifed index */
- (const char*)userDefaultValue:(int)ndx
{
	const char *val = _userDefaults[ndx].value;
	return (val && *val)? val : (char*)nil;
}

/* load defaults */
- (void)_loadDefaults
{
	int i;
	for (i = 0; _userDefaults[i].name; i++) {
		const char *val = [self readDefault:_userDefaults[i].name];
		_userDefaults[i].value = (char*)val;
	}
}

/* return deblanked string */
char *deblank(const char *val)
{
	int n;
	char *mval;
	if (!val) val = "";
	else { while (*val && isspace(*val)) val++; }
	mval = STRDUP(val);
	for (n = strlen(mval) - 1; (n >= 0) && isspace(mval[n]); n--) mval[n] = 0;
	return mval;
}

/* show preference panel */
- (void)showPreferences:(id)sender
{
	int dft, dftCnt = [dftObjList count];
	
	/* fill preference fields */
	for (dft = 0; dft < dftCnt; dft++) {
		id valObj = [dftObjList objectAt:dft];
		const char *val = _userDefaults[dft].value;

printf("Reading %d: \"%s\"\n", dft, [valObj name]);
		
		/* pre-filter */
		if (dft == xFLG_SHOWSECONDS) {
			if (!val) { val = "0"; }
			else { while (*val && isspace(*val)) val++; }
			[valObj setState:((*val=='2')?1:0)];
		} else
		if (dft == xCMD_TAILLOG) {
			char tmpBuff[1024], *mval;
			if (!val) { // look for a ppp log file
				char *c = "cat /etc/syslog.conf|grep /usr/adm/ppp|awk '{print $2;}'";
				FILE *pnum = popen(c,"r");
				if (pnum) {
					fgets(tmpBuff,sizeof(tmpBuff)-1,pnum);
					pclose(pnum);
					if (*tmpBuff) val = tmpBuff;
				}
				if (!val) val = "";
			} 
			mval = deblank(val);
			[valObj setStringValue:mval];
			free(mval);
		} else
		if (dft == xCMD_MINISHELF) {
			char *v, *mval;
			if (!val) { val = "/NextApps/Mail.app"; }
			mval = deblank(val);
			for (v = mval; *v; v++) { if (*v == ';') *v = '\n'; }
			[valObj setSel:0:[valObj textLength]];
			[valObj replaceSel:mval];
			free(mval);
		} else {
			char *mval = deblank(val);
			[valObj setStringValue:mval];
			free(mval);
		}
		
	}
	[prefPanel makeKeyAndOrderFront:sender];
}

/* cancel preferences */
- (void)prefBtnOK:(id)sender
{
	int dft;

	/* cancel */
	if ([sender tag] < 0) {
		[prefPanel orderOut:sender];
		return;
	}
	
	/* update */
	for (dft = 0; _userDefaults[dft].name; dft++) {
	
		/* update user defaults */
		if (dft < [dftObjList count]) {
			int len;
			id valObj = [dftObjList objectAt:dft];
			char buff[3000], *val = buff;
			
printf("Updating %d: \"%s\"\n", dft, [valObj name]);
			
			/* post filter */
			if (dft == xFLG_SHOWSECONDS) {
				val = [valObj state]? "2" : "0";
			} else
			if (dft == xCMD_PINGINTERVAL) {
				int interval = atoi([valObj stringValue]);
				if (interval < 60) interval = 60;
				[valObj setIntValue:interval];
				val = (char*)[valObj stringValue];
			} else
			if (dft == xCMD_MINISHELF) {
				len = [valObj getSubstring:buff start:0 length:sizeof(buff) - 1];
				if (len >= sizeof(buff)) buff[sizeof(buff) - 1] = 0;
				for (val = buff; *val; val++) { if (*val == '\n') *val = ';'; }
				while ((val > buff) && (*(val-1) == ' ')) *(--val) = 0;
				strcpy(val," ");
				val = buff;
			} else {
				val = (char*)[valObj stringValue];
			}
			while (*val && isspace(*val)) val++; // skip leading space
			
			/* write new value */
			NXWriteDefault([self appName], _userDefaults[dft].name, val);
		}
		
		/* read new value */
		_userDefaults[dft].value = 
			(char*)NXReadDefault([self appName],_userDefaults[dft].name);
	}
	[prefPanel orderOut:sender];
	[ExecMonitor updateFromDefaults];
	
}

// -------------------------------------------------------------------------------------
// OpenStep api support
// -------------------------------------------------------------------------------------

/* set application icon (OpenStep api) */
- (void)setApplicationIconImage:(NXImage*)image
{
	id              iconWin = [NXApp appIcon];      
	NXPoint         iconOrigin = { 0.0, 0.0 };
	NXSize          imageSize;
	static id       tileImage = (id)nil;
	static NXSize   tileSize = { 0.0, 0.0 };

	/* init dock icon tile */
	if (!tileImage && (tileImage = [NXImage findImageNamed:"NXAppTile"])) {
		[tileImage getSize:&tileSize];
	}

	/* redraw AppIcon */
	[[iconWin contentView] lockFocus];
	PSsetinstance(FALSE);
	[tileImage composite:NX_COPY toPoint:&iconOrigin];
	[tileImage getSize:&tileSize];
	[image getSize:&imageSize];
	iconOrigin.x = (tileSize.width  - imageSize.width ) / 2.0;
	iconOrigin.y = (tileSize.height - imageSize.height) / 2.0;
	[image composite:NX_SOVER toPoint:&iconOrigin];
	[[iconWin contentView] unlockFocus];
	[iconWin display];
  
}

// -------------------------------------------------------------------------------------
// application initialization
// -------------------------------------------------------------------------------------

/* application initialization */
- appDidInit:sender
{
	/* create user-default preferences object list */
	dftObjList = [[List alloc] init];
	[dftObjList addObject:dftCmdConnect];		// 0
	[dftObjList addObject:dftSndConnect];		// 1
	[dftObjList addObject:dftAppTileTimer];	    // 2
	[dftObjList addObject:dftCmdDisconnect];	// 3
	[dftObjList addObject:dftSndDisconnect];	// 4
	[dftObjList addObject:dftCmdTailLog];		// 5
	[dftObjList addObject:dftCmdPing];			// 6
	[dftObjList addObject:dftCmdPingInterval];	// 7
	[dftObjList addObject:dftMiniShelf];		// 8
	[dftObjList addObject:dftCmdLoadPPPLKS];	// 9

	/* load command defaults */
	[self _loadDefaults];

	/* create monitor */
	if (![ExecMonitor sharedPPPMonitor]) [self terminate:self];
	
	/* show preferences */
	if (!CMD_CONNECT || !CMD_DISCONNECT) {
		[NSApp errorPanel:"Define Connect/Disconnect commands before connecting\n"];
		[self showPreferences:nil];
	}
	
	return self;
}

@end
